/*
 * $Id: HandshakeController.java,v 1.16 2012/02/01 20:02:02 navdeep_mahajan Exp $
 * 
 * Copyright (C) 2008 General Electric Company. All Rights Reserved.
 * 
 * This software is the confidential and proprietary information of the General
 * Electric Company (GE). You shall not disclose this software and shall use it
 * only in accordance with the terms of the license agreement you entered into
 * with GE.
 * 
 * GE MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
 * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
 * NON-INFRINGEMENT. GE SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
 * AS A RESULT OF USING, MODIFYING, OR DISTRIBUTING THIS SOFTWARE OR ITS
 * DERIVATIVES.
 */
package com.ge.healthcare.autosc.onwatch.controller;

import java.io.IOException;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.validation.BindException;
import org.springframework.validation.ObjectError;
import org.springframework.web.servlet.ModelAndView;

import com.ge.healthcare.autosc.common.ASCLogger;
import com.ge.healthcare.autosc.common.ASCUtil;
import com.ge.healthcare.autosc.common.database.dao.IOnWatchSysHandShakeInfoDAO;
import com.ge.healthcare.autosc.common.database.pojo.HstSystemContactInfo;
import com.ge.healthcare.autosc.common.dbLogger.ContactLogger;
import com.ge.healthcare.autosc.onwatch.bean.HandshakeBean;
import com.ge.healthcare.autosc.onwatch.exception.OnWatchException;
import com.ge.healthcare.autosc.onwatch.pojo.ErrorCode;
import com.ge.healthcare.autosc.onwatch.service.IIPHttpClientPkgDownloader;
import com.ge.healthcare.autosc.onwatch.util.OnWatchConstants;
import com.ge.healthcare.autosc.onwatch.util.ResourceBundleUtil;

/**
 * HandshakeController is the HTTP controller for handshake request. It requests
 * Pending onwatch task for the requesting system, and return taskList in XML
 * format as HTTP response. This controller redirect to Error view in error
 * condition.
 * 
 * @author 212042946
 * 
 */
public class HandshakeController extends AbstractFormController {

	private static IOnWatchSysHandShakeInfoDAO sysHandShakeInfo = null;

	public void init() {
		super.init();
	}

	/**
	 * Override onSubmit from the superclass
	 */
	protected ModelAndView onSubmit(HttpServletRequest request,
			HttpServletResponse response, Object command, BindException errors)
			throws ServletException, IOException {
		String methodName = "onSubmit";
		ASCLogger.info(this.getClass(), "onSubmit", "iipVersion is : "
				+ request.getHeader("iipVersion"));
		ASCLogger.debug(this.getClass(), methodName, "On Submit called...");
		ContactLogger.startLogging(request.getRemoteAddr(),
				HstSystemContactInfo.HTTP_CONNECT_TYPE);
		ContactLogger.addContactLog("Handshake request");
		HandshakeBean handshakeBean = (HandshakeBean) command;
		ASCLogger.info(this.getClass(), methodName, "Process request\n"
				+ handshakeBean);
		this.transferPackage(request, handshakeBean);
		handshakeBean.setRemoteAddr(request.getRemoteAddr());
		checkSimulatorRequest(handshakeBean);
		String taskListXml = null;
		ModelAndView mav = null;
		try {
			// get the taskList xml string
			taskListXml = getOnWatchService().getOnwatchTaskList(handshakeBean);
			mav = new ModelAndView("xmlView");
			mav.addObject("content", taskListXml);
		} catch (OnWatchException owe) {
			ErrorCode errorCode = new ErrorCode(this.getClass().getName());
			errorCode.addCode("failed.handshake.detail");
			errorCode.AddErrorCodeAsArgument(getCodeDetailsDAO(),
					owe.getErrorCode());
			errors.addError(errorCode.getObjectError("Handshake failed"));
			mav = callError(request, response, errors);
		} catch (Throwable e) {
			ErrorCode errorCode = new ErrorCode(this.getClass().getName());
			errorCode.addCode("error.system.internal");
			errors.addError(errorCode.getObjectError("Internal System error"));
			mav = callError(request, response, errors);
		} finally {
			if (!handshakeBean.isRegistrationMode()) {
				this.updateOnWatchSysHandShakeInfo(handshakeBean);
			}
			ContactLogger.endLogging(null);
		}
		return mav;
	}

	/**
	 * Transfer IIPHttpClient on the remote device
	 * 
	 * @param request
	 * @param handshakeBean
	 */
	private void transferPackage(HttpServletRequest request,
			HandshakeBean handshakeBean) {
		if (ASCUtil.isNullOrEmpty(request.getHeader("iipVersion"))) {
			ASCLogger.info(this.getClass(), "transferPackage", "iipVersion is null");
			IIPHttpClientPkgDownloader downloader = new IIPHttpClientPkgDownloader(
					handshakeBean.getSystemId());
			try {
				downloader.execute();
				ASCLogger.info(this.getClass(), "transferPackage", "IIPHttpClientPkgDownloader successfully completed");
			} catch (OnWatchException onwatchException) {
				ASCLogger.error(this.getClass(), "transferPackage",
						"Failed to updated the IIPHttpClient on device",
						onwatchException);
				ContactLogger.addContactLog(handshakeBean.getSystemId(),
						"Failed to updated the IIPHttpClient on device:"
								+ onwatchException);
			}
		}
	}

	/**
	 * Updates the onwatch system contact info table with
	 * 
	 * @param systemContactInfo
	 */
	private void updateOnWatchSysHandShakeInfo(HandshakeBean handshakeBean) {
		Long nextPollDurationInMin = null;
		if (!ASCUtil.isNullOrEmptyObject(handshakeBean)) {
			nextPollDurationInMin = handshakeBean.getNextConnectTimeInLong();
		}
		HstSystemContactInfo systemContactInfo = ContactLogger
				.getSystemContactInfo();
		sysHandShakeInfo.saveContactInfo(systemContactInfo.getSystemId(),
				systemContactInfo.getContactTime(), nextPollDurationInMin * 60);
	}

	/**
	 * Override showForm from the superclass
	 */
	protected ModelAndView showForm(HttpServletRequest request,
			HttpServletResponse response, BindException errors)
			throws Exception {
		String methodName = "showForm";
		ASCLogger.debug(this.getClass(), methodName, "In showForm....");
		if (errors.hasErrors()) {
			super.logErrors(errors);
			Map<Object, Object> model = new HashMap<Object, Object>();
			/*
			 * If multiple errors, this comes from validation or binding. Only
			 * give remote system the first failed error when remote system
			 * suppose to know how to communicate.
			 */
			ObjectError err = (ObjectError) errors.getAllErrors().get(0);
			String errorMessage = ResourceBundleUtil.getMessage(
					OnWatchConstants.ONWATCH_MESSAGE_BASENAME, err.getCode(),
					err.getArguments(), err.getDefaultMessage(), null);
			ContactLogger.addContactLog("Error message: " + errorMessage);
			model.put("error", errorMessage);
			model.put("systemId", request.getParameter("systemId"));
			model.put("iipVersion", request.getParameter("iipVersion"));
			return new ModelAndView("errorView", model);
		}
		return null;
	}

	/**
	 * @param sysHandShakeInfo
	 *            the sysHandShakeInfo to set
	 */
	public void setSysHandShakeInfo(IOnWatchSysHandShakeInfoDAO sysHandShakeInfo) {
		HandshakeController.sysHandShakeInfo = sysHandShakeInfo;
	}
}
